﻿// -----------------------------------------------------------------------
// <copyright file="Projectile.cs" company="Diddly Squad">
// </copyright>
// -----------------------------------------------------------------------
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using FarseerPhysics.Factories;

namespace DiddlySquat
{
	/// <summary>
	/// Represents one bullet in the game, Created as Farseer body with isBullet = true.
	/// </summary>
	public class Projectile
	{
		public Body CircleBody { get; set; }
		public Texture2D CircleSprite { get; set; }
		public Vector2 CirclePosition { get; set; }
		public float Speed { get; set; }
		public Vector2 Direction { get; set; }
		public float Mass { get; set; }

		// Animation representing the Projectile
		public Animation ProjectileAnimation { get; private set; }

		// Position of the Projectile relative to the upper left side of the screen
		public Vector2 Position { get; private set; }

		// State of the Projectile
		public bool Active { get; private set; }

        private double damage;

		/// <summary>
		/// Initializes the projectile.
		/// </summary>
		/// <param name="world">The world.</param>
		/// <param name="position">The position.</param>
		/// <param name="speed">The speed.</param>
		/// <param name="direction">The direction.</param>
		/// <param name="sprite">The sprite.</param>
		public void Initialize(World world, Vector2 position, float speed, Vector2 direction, Texture2D sprite)
		{   
			Position = position;
			Speed = speed;
			Direction = direction;

            this.damage = Constants.BasicProjectileDamage;

			//Create new farseer body
			this.CircleBody = BodyFactory.CreateCircle(world, Constants.BasicProjectileSize, 1f, Position, this);
			this.CircleBody.BodyType = BodyType.Dynamic;

			this.CircleSprite = sprite;

			// Set the Projectile to be active
			Active = true;

			this.CircleBody.IsBullet = true;

            this.CircleBody.CollisionCategories = Constants.ProjectileCollisionCategory;
            this.CircleBody.CollidesWith = Constants.ProjectileCollidesWith;

            this.CircleBody.OnCollision += HandleCollision;

            //circleBody.Mass = 10;
		}

		/// <summary>
		/// Initializes the specified projectile.
		/// </summary>
		/// <param name="world">The world.</param>
		/// <param name="position">The position.</param>
		/// <param name="speed">The speed.</param>
		/// <param name="direction">The direction.</param>
		/// <param name="sprite">The sprite.</param>
		/// <param name="damage">The damage.</param>
        public void Initialize(World world, Vector2 position, float speed, Vector2 direction, Texture2D sprite, double damage)
        {
            this.Initialize(world, position, speed, direction, sprite);
            this.damage = damage;
        }

		/// <summary>
		/// Launches new projectile (shoots).
		/// </summary>
		public void Launch()
		{
			Vector2 shoot = Direction;
			Vector2.Multiply(ref shoot, Speed, out shoot);
			this.CircleBody.ApplyLinearImpulse(shoot);
		}

		/// <summary>
		/// Updates the Projectile animation
		/// </summary>
		/// <param name="gameTime">The game time.</param>
		public void Update(GameTime gameTime)
		{
			ProjectileAnimation.Position = Position;
			ProjectileAnimation.Update(gameTime);
		}

		/// <summary>
		/// Draws the projectile if active.
		/// </summary>
		/// <param name="spriteBatch">The sprite batch.</param>
		public void Draw(SpriteBatch spriteBatch)
		{
            if (Active)
            {
                spriteBatch.Draw(this.CircleSprite, this.CircleBody.Position * Constants.MeterInPixels, Color.White);
            }
		}

		/// <summary>
		/// Makes projectile inactive.
		/// </summary>
		public void Delete()
		{
			this.Active = false;
		}

		/// <summary>
		/// Gets the speed.
		/// </summary>
		/// <returns></returns>
        public double GetSpeed()
        {
            double speed = Math.Sqrt(((this.CircleBody.LinearVelocity.X * this.CircleBody.LinearVelocity.X) + (this.CircleBody.LinearVelocity.Y * this.CircleBody.LinearVelocity.Y)));
            return speed;
        }

		/// <summary>
		/// Handles the collision.
		/// </summary>
		/// <param name="a">This projectile</param>
		/// <param name="b">Target</param>
		/// <param name="c">Contact type</param>
		/// <returns></returns>
        private bool HandleCollision(Fixture a, Fixture b, FarseerPhysics.Dynamics.Contacts.Contact c)
        {
            if (b.UserData is Enemy)
            {
                var enemy = (Enemy)b.UserData;
                enemy.Hit(this.damage);
            }
            return true;
        }

	}
}
